home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / answrbok / 4_12.lha / 4_12 / 4_12c.c < prev    next >
C/C++ Source or Header  |  1993-08-08  |  3KB  |  160 lines

  1. * Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
  2. * The C++ Answer Book */
  3. * Tony Hansen */
  4. * All rights reserved. */
  5. include <stream.h>
  6. include <sys/types.h>
  7. ypedef unsigned short ushort;
  8. include <sys/stat.h>
  9. include <memory.h>
  10. include <ctype.h>
  11. include <fcntl.h>
  12. include <osfcn.h>
  13.  
  14. nt sizefile(char* filename)
  15.  
  16.    struct stat statbuf;
  17.    if (stat(filename, &statbuf) != -1)
  18. return statbuf.st_size;
  19.    else
  20. return 0;
  21.  
  22.  
  23. oid error(char* msg)
  24.  
  25.    cerr << msg << "\n";
  26.    exit(1);
  27.  
  28.  
  29. oid readfile(char* filename, int filelen, char* filebfr)
  30.  
  31.    int fd = open(filename, O_RDONLY);
  32.    if (fd < 0)
  33. error("cannot open file");
  34.    if (read(fd, filebfr, filelen) != filelen)
  35. error("bytes read != size of file");
  36.    close(fd);
  37.  
  38.  
  39. nt matchcount(char* bufptr1, char* bufptr2)
  40.  
  41.    int ctr = 0;
  42.    while (*bufptr1++ == *bufptr2++)
  43. ctr++;
  44.    return ctr;
  45.  
  46.  
  47. oid dochar(char c)
  48.  
  49.    if (isprint(c))
  50. {
  51. cout.put(c);
  52. cout.put('_');
  53. }
  54.    else
  55. cout << form("%2.2x", c);
  56.  
  57.  
  58. oid prfactors(int max)
  59.  
  60.    int j = max / 2;
  61.    for (int i = 2; i <= j; i++)
  62.        if (max % i == 0)
  63.     cout << dec(i, 3);
  64.    cout << dec(max, 3) << "\n";
  65.  
  66.  
  67. oid prperiods(int)
  68.  
  69.  
  70.  
  71. onst int NUMperiods = 150;
  72. truct
  73.  
  74.    int begin;
  75.    int length;
  76.  periodlist[NUMperiods] = { { -1, 0 } };
  77.  
  78. oid addperiods(int begin, int interval, int cnt, int filelen)
  79.  
  80.    /* collapse old period info out */
  81.    for (int left = 0; periodlist[left].begin != -1; left++)
  82. if (periodlist[left].begin < begin)
  83.     {
  84.     int right = left + 1;
  85.     periodlist[left] = periodlist[right];
  86.     for ( ; periodlist[right].begin != -1; )
  87.         if (periodlist[++right].begin >= begin)
  88.         periodlist[left++] = periodlist[right];
  89.     }
  90.    
  91.    /* At this point, periodlist[left].begin == -1. */
  92.    /* We now add the new values. */
  93.    for (int i = begin + 1; (left < NUMperiods) && (--cnt > 0); )
  94. for (int j = i; (j < filelen) && (left < NUMperiods); j += interval)
  95.     {
  96.     periodlist[left].begin = j;
  97.     periodlist[left++].length = cnt;
  98.     }
  99.  
  100.    if (left == NUMperiods)
  101.        error("too many periods to add");
  102.  
  103.  
  104. nt foundperiod(int begin, int length)
  105.  
  106.    for (int i = 0; (i < NUMperiods) && (periodlist[i].begin != -1); i++)
  107. if ((periodlist[i].begin == begin) &&
  108.     (periodlist[i].length == length))
  109.     return 1;
  110.    return 0;
  111.  
  112.  
  113. oid pr_common_periods()
  114.  
  115.  
  116.  
  117. ain(int argc, char **argv)
  118.  
  119.    if (argc != 2)
  120. {
  121. cerr << "usage: " << argv[0] << " encrypted-file\n";
  122. return 1;
  123. }
  124.  
  125.    char* filename = argv[1];
  126.    int filelen = sizefile(filename);
  127.    char* filebfr = new char[filelen];
  128.    readfile(filename, filelen, filebfr);
  129.  
  130.    cout << "length  string\n";
  131.    cout << "1st pos  2nd pos  interval\n";
  132.    cout << "factors  periods\n\n";
  133.    for (int i = 0; i < filelen - 3; i++)
  134. {
  135. for (char* bufptr = &filebfr[i+3];
  136.      bufptr = memchr(bufptr,filebfr[i], filelen - (bufptr - filebfr));
  137.      bufptr++)
  138.     {
  139.     int cnt = matchcount(filebfr+i+1, bufptr+1);
  140.     if ((cnt > 2) && !foundperiod(i, cnt))
  141.     {
  142.     int interval = (bufptr - filebfr) - i;
  143.     addperiods(i, interval, cnt, filelen);
  144.     cout << cnt << "  ";
  145.     for (char* p = bufptr; cnt--; p++ )
  146.         dochar(*p);
  147.     cout << "\n" << i << "  " << (bufptr - filebfr) << "  " <<
  148.         interval << "\n";
  149.     prfactors(interval);
  150.     prperiods(interval);
  151.     cout << "\n";
  152.     break;
  153.     }
  154.     }
  155. }
  156.  
  157.    pr_common_periods();
  158.    return 0;
  159.  
  160.